<!-- 路径规划组件 -->
<!-- 操作：面板上选择起点和终点，然后点击进入规划模式，进行路径规划 -->
<!-- 路径规划期间，将禁用图层控制，并将图层隐藏，展示路径规划实体以及规划面板 -->
<!-- 点击离开规划，恢复图层控制，并清除规划的结果，隐藏规划面板 -->
<template>
    <div class="route-design-wrapper">
        <div class="route-design">
            <div class="header">
                <i class="iconfont metro-lujingguihua"></i>
                <span>路径规划</span>
                <button class="start-btn" @click="pressDesign">
                    {{ isDesign ? "离开规划模式" : "进入规划模式" }}
                </button>
            </div>
            <div class="content">
                <div>
                    <span style="margin-right: 5px">起点:</span>
                    <a-cascader
                        v-model:value="startStation"
                        :options="options"
                        placeholder="请输入起点站"
                    >
                        <template #clearIcon>
                            <i class="iconfont metro-close"></i>
                        </template>
                    </a-cascader>
                    <!-- <a-button style="margin-left: 8px" @click="pickStation('origin')">拾取起点站</a-button> -->
                </div>
                <div>
                    <span style="margin-right: 5px">终点:</span>
                    <a-cascader
                        v-model:value="endStation"
                        :options="options"
                        placeholder="请输入终点站"
                        ><template #clearIcon>
                            <i class="iconfont metro-close"></i>
                        </template>
                    </a-cascader>
                </div>
            </div>
        </div>
    </div>
    <!-- 路径规划展示面板 -->
    <PathDesignDisplayCard
        :routeInfo="routeInfo"
        v-if="isDesign"
        :cacheData="cacheData"
    />
</template>
<script setup>
import { onBeforeUnmount, onMounted, ref, watch } from "vue";
import { message } from "ant-design-vue";
import {
    renderStationBill,
    renderLines,
    renderStation,
    flyToDefaultView,
    removeByCacheData,
} from "@/cesiumTools/LineMaterial/effectController";
import { useLineData, watchLineData } from "@/store/index";
import { getLinePlan } from "@/api/line";
import { lineColors } from "@/store/staticData";
import PathDesignDisplayCard from "@/views/Stationmanager/PathDesignDisplayCard.vue";
import * as Cesium from "cesium";

const isDesign = ref(false); //是否进入规划模式
const routeInfo = ref({}); //路径规划结果
const cacheData = {
    stationEnts: [],
    billboards: [],
    lineEnts: [],
}; //缓存地图渲染数据
const options = ref([]); //站点列表
const startStation = ref([]); //起点站
const endStation = ref([]); //终点站

let stationFlag = {}; //站点标志,用于判断是否发生变化

const lineDataStore = useLineData();

let viewer;

const getPositon = (lineName, stationName) => {
    const targetLine = lineDataStore.lineData.find((l) => l.name === lineName);
    const { position } = targetLine.stationsList.find(
        (s) => s.name === stationName
    );
    return `${position.lng},${position.lat}`;
};

//整理路径规划结果
const getRouteInfo = (pathInfo) => {
    const stations = [];
    const paths = [];
    const route = {
        stations: [],
    };
    const { distance, segments } = pathInfo;
    route.distance = distance;
    segments.forEach((segment, sIndex) => {
        const { buslines } = segment.bus;
        if (buslines && buslines.length > 0) {
            const target = buslines[0];
            const color = lineColors[sIndex];
            target.color = color;
            route.stations.push(target);

            buslines.forEach((b, index) => {
                const line = { part: index + 1, partStation: [] };
                const {
                    type,
                    arrival_stop,
                    departure_stop,
                    name,
                    polyline,
                    via_stops,
                } = b;
                paths.push({
                    name,
                    part: index + 1,
                    polyline,
                });
                if (type === "地铁线路") {
                    // 先加入起点站
                    let arrival = arrival_stop;
                    let departure = departure_stop;
                    // 如果是最后一段线路，为终点站，否则为换乘站
                    arrival.type =
                        sIndex === segments.length - 1 ? "终点站" : "换乘站";
                    // 如果是第一段线路，为起点站，否则为换乘站
                    departure.type = sIndex === 0 ? "起点站" : "换乘站";

                    line.partStation.push(arrival);
                    via_stops.forEach((v) => {
                        v.type = "途径站";
                        line.partStation.push(v);
                    });

                    line.partStation.push(departure);
                    line.name = name;
                }
                stations.push(line);
            });
        }
    });
    routeInfo.value = route;
    //缓存标志
    stationFlag = {
        cacheStart: startStation.value,
        cacheEnd: endStation.value,
    };
    return { stations, paths, distance };
};

//判断是否发生变化
const hasChange = () => {
    if (!stationFlag.cacheStart || !stationFlag.cacheEnd) {
        return true;
    }
    const start = startStation.value;
    const end = endStation.value;
    console.log(stationFlag);
    const { cacheStart, cacheEnd } = stationFlag;
    return (
        start[0] !== cacheStart[0] ||
        start[1] !== cacheStart[1] ||
        end[0] !== cacheEnd[0] ||
        end[1] !== cacheEnd[1]
    );
};

//渲染路径规划要素
const renderRouteDesign = ({ paths, stations }) => {
    //渲染站点
    stations.forEach((station, sIndex) => {
        let color = lineColors[sIndex];
        const { name, partStation } = station;
        // 添加站点
        partStation.forEach(async (p) => {
            let { location, name, type } = p;
            name = type === "换乘站" ? name + "(换乘)" : name;
            const positionArr = location.split(",").map((item) => Number(item));
            const position = { lng: positionArr[0], lat: positionArr[1] };
            // 这里不能走缓存，因为name不一样，会污染后续的功能
            const stationEnt = renderStation(viewer, {
                positions: position,
                name,
                color: type === "换乘站" ? "#e9a526" : color,
            });
            const billboard = await renderStationBill(viewer, {
                position,
                name,
                color: type === "换乘站" ? "#e9a526" : color,
                attr: {
                    name,
                },
            });
            // 存放在组件中
            cacheData.stationEnts.push(stationEnt);
            cacheData.billboards.push(billboard);
        });
    });

    //渲染路径
    paths.forEach((path, pIndex) => {
        const { name, part, polyline } = path;
        const positions = polyline.polyline.split(";");
        const positionsArr = positions.map((item) =>
            item.split(",").map((i) => Number(i))
        );
        const color = lineColors[pIndex];
        const lineEnt = renderLines(viewer, {
            positions: positionsArr.flat(2), // 二维数组转一维数组
            color: new Cesium.Color.fromCssColorString(color),
            name,
        });
        cacheData.lineEnts.push(lineEnt);
    });
    //飞行到默认视角
    flyToDefaultView(viewer);
};

//刷新路径规划结果
const refreshRouteDesign = async () => {
    //移除上次数据
    removeByCacheData(viewer, cacheData);
    cacheData.billboards=[]
    cacheData.lineEnts=[]
    cacheData.stationEnts=[]

    //获取起点终点坐标
    let params = {};
    const start = startStation.value;
    const end = endStation.value;
    // // 从lineData中获取坐标信息
    params.origin = getPositon(start[0], start[1]);
    params.destination = getPositon(end[0], end[1]);
    let routePlan;
    try {
        routePlan = await getLinePlan(params);
        if (routePlan.code !== 200) {
            message.warning("规划查询失败");
            return;
        }
    } catch (error) {
        message.error("规划查询失败");
        return;
    }
    //获取路径规划结果
    let res = getRouteInfo(routePlan.data);
    //实时渲染要素
    renderRouteDesign(res);
};

//点击规划位置
const pressDesign = async () => {
    if (isDesign.value) {
        //退出规划模式
        isDesign.value = false;
        //清除缓存数据
        removeByCacheData(viewer, cacheData);
        cacheData.billboards=[]
        cacheData.lineEnts=[]
        cacheData.stationEnts=[]
        startStation.value = [];
        endStation.value = [];
        pathInfo.value = {};
        //恢复图层控制
        return;
    }

    if (startStation.value.length === 0 || endStation.value.length === 0) {
        message.error("请选择起点和终点站");
        return;
    }
    

    //缓存逻辑
    if (hasChange() === false) {
        return;
    }
    //刷新路径规划结果
    await refreshRouteDesign();

    //显示路径规划面板
    isDesign.value = true;
};

onMounted(async () => {
    viewer = lineDataStore.viewer;
    let lineData = await watchLineData();
    options.value = lineData.map((item) => ({
        value: item.name,
        label: item.name,
        const: item.name,
        children: item.stationsList.map((station) => ({
            value: station.name,
            label: station.name,
        })),
    }));
});

onBeforeUnmount(() => {
    removeByCacheData(viewer, cacheData);
});

//路径规划模式下，实时渲染
watch([startStation, endStation], () => {
    if (isDesign.value) {
        //实时渲染
        refreshRouteDesign();
    }
});
</script>
<style scoped>
/* 路径规划样式 */
.route-design-wrapper {
    position: absolute;
    right: 14%;
    top: 5%;
}

.route-design {
    width: 320px;
    height: 170px;
    background-color: rgba(0, 0, 0, 0.6);
    border: 1px solid #885f12;
}

.route-design > .header {
    width: 100%;
    height: 40px;
    color: #fff;
    padding-left: 10px;
    background: rgb(255, 255, 255);
    background-image: linear-gradient(
        180deg,
        rgba(255, 255, 255, 1) 9%,
        rgba(211, 156, 50, 1) 57%
    );
    -webkit-background-clip: text;
    -webkit-text-fill-color: transparent;
    display: flex;
    align-items: center;
}

.route-design span {
    margin-left: 5px;
}

.content {
    width: 100%;
    height: 110px;
    pointer-events: all;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: space-around;
    color: #fff;
}

.start-btn {
    width: 80px;
    color: #fff;
    margin-left: 140px;
    background-color: transparent;
    border: 1px solid #885f12;
    font-size: 12px;
    padding: 3px;
    pointer-events: all;
    cursor: pointer;
}

.start-btn:hover {
    background-color: #5c3f096d;
    border: 1px solid #881212;
}
:deep(.ant-select:not(.ant-select-customize-input) .ant-select-selector){
    background-color: #1a222b;
}
:deep(.ant-select-selection-placeholder){
    color: #fff;
}
:deep(.ant-select-single .ant-select-selector){
    color: #fff;
}
:deep(.ant-cascader-menu-item-active){
    background-color: #144e56;
}

:global(.ant-cascader-menus) {
    background-color: #1a222b;
    color: #fff;
}

:global(.ant-cascader-menu){
    /* 滚动条设置,禁用*/
    overflow: hidden;

}
:global(.ant-cascader-menu-item-expand-icon){
color: #adabab;
}
:global(.ant-cascader-dropdown .ant-cascader-menu-item-active:not(.ant-cascader-menu-item-disabled)){
    background-color: #144e56;
}
</style>
